<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;             // 引入模型
use Illuminate\Http\Request;

use Illuminate\Support\Facades\Validator;     // 后台表单验证
use Illuminate\Support\Facades\Hash;           // 哈希加密
use Illuminate\Support\Facades\Crypt;
use Mockery\Exception;           // crypt加密


//require ('..\Utils\responseTool.php');         // 引入自定义模块(无效)
//require ('/Utils/responseTool.php');         // 引入自定义模块(无效)
//use App\Http\Controllers\Utils;              // 无法引入

class LoginController extends Controller {


    /* 登录账号， post */
    public function login(Request $request){

        // 1、接收表单提交的数据
        $input = $request->all() ;
        // 或者  $input = request(['username', 'password']);
        //相当于python的POST.dict()

        //2．进行表单验证
        $rule = [
            'username'=>'required|between:2,18',
            'password'=>'required|between:6,18|alpha_dash',
        ];
        $msg = [
            'username.required'=>'用户名不能为空',
            'username.between'=>'用户名长度必须在2-18位之间',
            'password.required'=>'密码不能为空',
            'password.between'=>'密码长度必须在6-18位之间',
            'password.alpha_dash'=>'密码必须是数组字母下滑线',
        ];
        $validator = Validator::make($input,$rule,$msg) ;   // 表单数据, 验证规则, 错误信息
        if ($validator->fails()) {
            return  $this->responseTool($validator,null,403);
        }


        // 3. 查询用户信息（首个昵称用户）
        //$user = User::where(["username"=>$input['username'],"password"=>$input['password']])->first();
        // 相当于 User.objects.filter(nickname=nickname, sex=1).first ()
        $user = User::where(["username"=>$input['username']]);


        // 4.加密当前用户密码信息查询
        $res_pwd = $this->verifyPwd($user->first ()["password"],'decrypt',$input['password']);
        if(!$res_pwd){
            return  $this->responseTool('密码错误！请重试',null,400);
        }else{
            $token = $this->verifyToken($user->first ());
            if (!$token  ) {
                return response()->json(['error' => '生成token失败！'], 500);
            }else{
                $res = $user->update(['token'=>$token]);
//              return response()->json(['msg' => '登录成功','code'=>200,'token' => $token]);
//              return  $this->responseTool('登录成功',null,200, $token);
              return $this->responseToken($token);
            }
        }
    }

    /* 退出登录, get */
    public function logout(Request $request)  {
       //  php不允许请求头上的字段带有下划线的数据_,因为它会默认转换为-
       //  php不允许请求头上的字段带有驼峰习惯的数据,因为它会默认转换为小写
        $res = $request->header();
        $accesstoken = str_replace("bearer-","",$res['access-token'][0]);

        // 解析出用户信息， 再删除当前保存的token
        // 1.解析用户信息
        $userinfo = $this->verifyToken($accesstoken,'decrypt');

        // 2.清空当前用户的token
        $user = User::where(["username"=> $userinfo['username']]);
        if($user->first()){
            $res = $user->update(['token'=>null]);
        }
        return response()->json(['msg' => '退出登录成功！', 'code' => 204]);

    }


    /* 注册账号， post */
    public function register(Request $request){

        // 1、接收表单提交的数据
        $input = $request->all() ;
        // 或者  $input = request(['username', 'password']);
        //相当于python的POST.dict()

        //2．进行表单验证
        $rule = [
            'username'=>'required|between:2,18',
            'password'=>'required|between:6,18|alpha_dash',
            'sex'=>'required',
            'address'=>'required',
        ];
        $msg = [
            'username.required'=>'用户名不能为空',
            'username.between'=>'用户名长度必须在2-18位之间',
            'password.required'=>'密码不能为空',
            'password.between'=>'密码长度必须在6-18位之间',
            'password.alpha_dash'=>'密码必须是数组字母下滑线',
            'sex.required'=>'性别不能为空',
            'address.required'=>'地址不能为空',
        ];

        $validator = Validator::make($input,$rule,$msg) ;   // 表单数据, 验证规则, 错误信息
        if ($validator->fails()) {
            return  $this->responseTool($validator,null,403);
        }

        // 3.加密用户密码与新增数据
        $input['password'] = $this->verifyPwd($input['password']);
        $input["registerTime"] =  date('Y-m-d h:i:s', time());
        $input["isDelete"] =  '0';


        // 4.检查是否有同名的用户（禁止）
        $res_user = User::where(["username"=> $input['username']])->first();
        if($res_user){
            return $this->responseTool('注册失败！该用户名已经被注册',null,403 );
        }else{
            // 5. 创建用户信息
            $user = User::create($input);
            return $this->responseTool('注册成功！',null,200 );
        }
    }

    /* 注销账号, get */
    public function unregister(Request $request)  {
        //  php不允许请求头上的字段带有下划线的数据_,因为它会默认转换为-
        //  php不允许请求头上的字段带有驼峰习惯的数据,因为它会默认转换为小写
        // 帐号不完全注销，只是设置隐藏的标志位
        $res = $request->header();
        $accesstoken = str_replace("bearer-","",$res['access-token'][0]);

        // 解析出用户信息， 再删除当前保存的token
        // 1.解析用户信息
        $userinfo = $this->verifyToken($accesstoken,'decrypt');

        // 2.清空当前用户的token
        $user = User::where(["username"=> $userinfo['username']]);
        if($user->first()){
            $res = $user->update(['token'=>null,'deleteTime'=>date('Y-m-d h:i:s', time()) ,'isDelete' => '1']);
        }
        return response()->json(['msg' => '注销账号成功！', 'code' => 204]);
    }




   //    工具类
    /* 返回token相关的数据*/
    protected function responseToken($token){
        return response()->json([
            'msg'=>'登录成功！',
            'access-token' => $token,
            'token-type' => 'bearer',
            'expires-in' => auth('api')->factory()->getTTL() / (60 * 24 ) . '天',
            'code'=>'200'
        ]);
    }

    /* 响应的工具方法 */
    //  return {msg:$msg, data:$data,code:$code};
    //  php没有对象与字典，但它的字符串索引数组就是类似结构
    public function responseTool($msg,  $data, $code, $token=null){
        if($token){
            return array('msg'=>$msg,'data'=>$data,'code'=>$code,'token'=>$token);
        }else{
            return array('msg'=>$msg,'data'=>$data,'code'=>$code);
        }
    }

    /* 密码Crypt加密算法 */
    public function verifyPwd($str, $mode="encrypt",$val=null){
        if ($mode == 'encrypt') {
            return Crypt::encrypt($str);   // 加密
        } else {
            if ($val == Crypt::decrypt($str)) {  // 解密
                return true;
            } else {
                return false;
            }
        }
    }

    
    /* token加密算法 */
    public function verifyToken($str, $mode="encrypt"){
        if ($mode == 'encrypt') {
            // 传递从数据库返回的信息
            $user = $str;
            return auth('api')->login($user);
        } else {
            // 传递需要解析的token
            $accesstoken = $str;
            auth('api')->setToken($accesstoken);
            return auth('api')->user(); 
        }
    }

}
